package com.alfayun.fiscalriskanalysis.user;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.alfayun.fiscalriskanalysis.enterprise.NoSuchEnterpriseException;
import com.google.common.collect.Streams;

@Service
public final class UserService {

	@Autowired
	private UserRepository repository;

	public UserVo createClientUser(UserVo user) throws NoSuchEnterpriseException {
		return new UserVo(User.create(repository, new User(user)));
	}

	public UserVo queryById(int id) throws NoSuchUserException {
		return repository.findById(id).map(UserVo::new).orElseThrow(NoSuchUserException::new);
	}

	public int delete(int id) {
		return repository.deleteById(id);
	}

	public UserVo modify(UserVo user) throws NoSuchUserException {
		Optional<User> row = repository.findById(user.id);

		if (row.isPresent()) {
			if ("".equals(user.password)) {
				user.password = row.get().password;
			} else {
				user.password = new BCryptPasswordEncoder().encode(user.password);
			}

			return new UserVo(repository.save(new User(user)));
		}

		throw new NoSuchUserException();
	}

	public List<UserVo> list() {
		return Streams.stream(repository.findAll()).map(UserVo::new).collect(Collectors.toList());
	}

	public Page<UserVo> page(int page, int size) {
		return repository.findAll(PageRequest.of(page, size, Sort.by("id"))).map(UserVo::new);
	}

	public List<UserVo> admins() {
		return repository.findByRole(Role.ADMIN).stream().map(UserVo::new).collect(Collectors.toList());
	}

	public User createAdminUser(User user) {
		return User.create(repository, user);
	}

	public User findUser(String username) {
		return repository.findByUsername(username);
	}

}
